package nl.hanze.designpatterns.io;

import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;


public class CryptedOutputStream extends OutputStream {
	
	private Cipher cipher;
	private SecretKeySpec secretkeyspec;
	
	private OutputStream outputStream;

	public CryptedOutputStream(OutputStream outputStream, byte[] hashKey) {
		// TODO Auto-generated constructor stub
		this.secretkeyspec = new SecretKeySpec(hashKey, "AES");
		this.outputStream = outputStream;
	}
	
	private void init() throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException{
		this.cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		this.cipher.init(Cipher.ENCRYPT_MODE, this.secretkeyspec);	
	}


	@Override
	public void write(int b) throws IOException {
		try {
			this.init();
			
			byte[] encryptData = {(byte) b};
			byte[] encryptedData = this.cipher.doFinal(encryptData);
			
			if(encryptedData.length != 16){
				throw new IllegalStateException(String.format("Encryption to short expected length of 16", encryptedData.length));
			}
			
			this.outputStream.write(encryptedData);
			
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

	}
	
	
}
